-
Notifications
You must be signed in to change notification settings - Fork 2
Add the facility to override the request timeout per include and route. #28
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the work! Three things seem important to me:
- I could not find the code that uses the timeout configured at the route - maybe I missed it...
- One test seems to not assert anything
- In an equals() method you compare Optionals with ==
Could you please fix these, (and, if you like, consider the other comments). Thanks!
private FetchContext(final String path, final String fallback, final Optional<Duration> ttl) { | ||
this.path = path; | ||
this.fallback = fallback; | ||
this.ttl = requireNonNull(ttl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why requireNonNull
for ttl but not for path or fallback? I really start to feel we need to find some consistent rule for these checks...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path and fallback is used as if it is valid to have null in there...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. But than, maybe Optional is better for both. I would like to have a codebase where null is always a mistake ;-)
I'll open an issue to discuss this kind of global code style questions, ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect.
@@ -41,6 +41,10 @@ private ContentRange contentRange() { | |||
return contentMarkupHandler.assets(); | |||
} | |||
|
|||
List<IncludedService> includedServices() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this is only accessible for testing, maybe add the @VisibleForTesting
annotation? We have not discussed whether we want to use this annotation, but I'd like to try it to see if it improves readability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about this, however we have three VisibleForTesting on the classpath, and none is from a dependency that is referenced in our pom directly. I would prefer to add my own annotation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree and apologize, because I used one of the three in my last PR. Should we add our own dependency to whatever small annotation lib provides this annotation? I don't think we should implement our own annotation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used VisibleForTesting from guava for now.
final CompositionStep step) { | ||
if (path == null || path.trim().isEmpty()) { | ||
public CompletableFuture<Response<String>> fetch(final FetchContext context, final CompositionStep step) { | ||
if (context.path() == null || context.path().trim().isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a method like FetchContext.hasEmptyPath()
or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally agree, btw. this is the cause why I did not prevent null for path and fallback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
.toCompletableFuture(); | ||
} | ||
|
||
private Request withTtl(final Request request, final FetchContext context) { | ||
if (context.ttl().isPresent()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like context.ttl().map(ttl -> request.withTtl(ttl)).orElse(request)
more than the if
construct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imho it is taste... changed.
final Match other = (Match) obj; | ||
return Objects.equals(backend, other.backend) && routeType == other.routeType; | ||
return Objects.equals(backend, other.backend) && routeType == other.routeType && ttl == other.ttl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you want to use Objects.equals(ttl, other.ttl)
instead of ==
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
assertThat(localRules).anySatisfy(rule -> { | ||
final Match routeMatchWithTtl = | ||
Match.of("https://target.service/{arg}", Optional.of(ofMillis(200)), PROXY); | ||
assertThat(routeMatchWithTtl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think here is some actual assertion missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh!
final List<Rule<Match>> localRules = configuration.localRules(); | ||
assertThat(localRules).anySatisfy(rule -> { | ||
final Match routeMatchWithTtl = | ||
Match.of("https://target.service/{arg}", Optional.of(ofMillis(200)), PROXY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think i don't like the static import of Duration.ofMillis
, because Duration.ofMills(200)
makes more sense to me than just ofMillis(200)
} | ||
|
||
public String backend() { | ||
return backend; | ||
} | ||
|
||
public Optional<Duration> ttl() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be me not understanding the coverage report, but it looks like this new method is not covered by any test?
} | ||
|
||
public List<Rule<Match>> localRules() { | ||
return localRoutes; | ||
} | ||
|
||
private static Optional<Duration> optionalDuration(final Config config, final String path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use com.spotify.apollo.environment.ConfigUtil
here instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That utility is private and final
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my classpath it is public final class ConfigUtil
, from dependency com/spotify/apollo-environment/1.6.3/apollo-environment-1.6.3.jar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My fault, I do not really remember why I rolled my own impl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no version for Duration, therefore I rolled my own impl.
final String unparsedValue = attributes.get(name); | ||
try { | ||
return Optional.of(Long.parseLong(unparsedValue)); | ||
} catch (final NumberFormatException nfEx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a test showing what happens when the data type is wrong?
Todo: Add E2E test. |
Ah darn, right after merging this: Could you update the readme.md to document the new features? |
No description provided.